package ThreadDemo;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;

public class BlockingQueueTest {
    public static void main4(String[] args) {
        BlockingQueue<Integer> queue = new PriorityBlockingQueue<>();
    }
    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<Integer> queue = new PriorityBlockingQueue<>();

        //创建多线程测试take(),pull()方法的线程安全性
        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    queue.put(i);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Thread1 - " + "put(" + i + ")");
            }
        });

        Thread thread2 = new Thread(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            for (int i = 0; i < 100; i++) {
                try {
                    queue.take();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Thread2 - " + "take(" + i + ")");
            }
        });

        thread1.start();
        thread2.start();

        thread1.join();
        thread2.join();

        //结论：
        //take()方法会保证线程安全，并且队列为空尝试从队列取出元素，会出发阻塞等待
        //pull()方法会保证线程安全，但是队列为空尝试从队列取出元素，不会触发阻塞等待，而是直接返回null值

    }
    public static void main2(String[] args) {
        BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);

        // 创建多个线程来测试offer()方法的线程安全性
        Thread producer1 = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try{
                    queue.put(i);
                }catch(InterruptedException E){
                    E.printStackTrace();
                }
                System.out.println("Produced " + i + " (success: " + ")");
            }
        });

        Thread producer2 = new Thread(() -> {
            for (int i = 10; i < 20; i++) {
                try{
                    queue.put(i);
                }catch(InterruptedException E){
                    E.printStackTrace();
                }
                System.out.println("Produced " + i + " (success: " + ")");
            }
        });

        producer1.start();
        producer2.start();

        try {
            producer1.join();
            producer2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 打印队列中的元素
        System.out.println("Queue contents: " + queue);

        //结论：
        //add()方法不能保证线程安全，一旦队列满了尝试插入元素，抛出异常
        //put()方法保证线程安全，队列满了，尝试插入元素，触发阻塞等待
        //offer()保证线程安全，但是队列满了，尝试插入元素，不会触发阻塞等待，直接返回false

    }

    public static void main1(String[] args) {
        BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);

        // 创建多个线程来测试offer()方法的线程安全性
        Thread producer1 = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                boolean success = queue.add(i);
                System.out.println("Produced " + i + " (success: " + success + ")");
            }
        });

        Thread producer2 = new Thread(() -> {
            for (int i = 10; i < 20; i++) {
                boolean success = queue.add(i);
                System.out.println("Produced " + i + " (success: " + success + ")");
            }
        });

        producer1.start();
        producer2.start();

        try {
            producer1.join();
            producer2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 打印队列中的元素
        System.out.println("Queue contents: " + queue);
    }
}